﻿#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include "N_KAnalysis.h"
#include <BPAFilesIO.h>
#include <io.h>
#include "time.h"
#include <boost/algorithm/string.hpp>
#include <Windows.h>
#include <string>
#include "shlwapi.h"
#include <BaseCommon.h>
#include <direct.h>
#include "BPAInterface.h"

using namespace JGG;
using namespace std;
namespace BPA{
    namespace impl{
        N_KAnalysis::N_KAnalysis()
        {
        }
        N_KAnalysis::~N_KAnalysis()
        {
        }

        void N_KAnalysis::InitConfig()
        {
            SqliteHelperDataBase db;
            db.open(database);

            ostringstream oss;

            // insert BaseName into FileList table if there is no base name
            // TODO: insert into ContrInfor
            oss.str("");
            oss << "SELECT * FROM FileList WHERE CaseID = " << caseid << ";";
            JGG::SqliteHelperTable file_list = db.getTable(oss.str().c_str());

            oss.str("");
            oss << "UPDATE FileList SET BaseName = '"
                << file_list.getStringField("CaseName") << ".BSE' "
                << "WHERE CaseID = " << caseid << ";";
            db.execDML(oss.str().c_str());


            // crate temp directory

            // TODO: 需要删除该文件夹下所有的文件
            string dir = "./bpa_temp/static_analysis_temp/";
            if (!JGG::filesystem::CDirectory::isdir(dir))
            {
                JGG::filesystem::CDirectory::mkdir(dir);
            }
            else
            {
                JGG::filesystem::CDirectory::rmdir(dir);
                JGG::filesystem::CDirectory::mkdir(dir);
            }

            const char* outdat = "./bpa_temp/static_analysis_temp/dat_temp.dat";
            BPAFileWriteBack(database, outdat, caseid);
            // copy pfnt.exe
            const string origpfnt = "./pfnt.exe";
            const string newpfnt = "./bpa_temp/static_analysis_temp/pfnt.exe";
            if (filesystem::CFile::exists(origpfnt))
            {
                filesystem::CFile::copy(origpfnt, newpfnt);
            }
            else
            {
                // TODO: log 缺少pfnt.exe!;
            }

            db.close();
        }

        bool N_KAnalysis::N_1Analysis()
        {
            string in_file = "dat_temp.dat";
            string out_file = "dat_temp_N-1.dat";

            // get .bse file
            DatWriteBack obj(database, caseid, Zone, Voltage, in_file, out_file);
            obj.GetN_1DatFromDb();
            CallPfnt(in_file);

            string pfo_file_path = "./bpa_temp/static_analysis_temp/dat_temp.pfo";
            BPAFilesIO::PfoParse pfoparser(database, caseid, pfo_file_path);
            pfoparser.N_1PfoParse();
            if (pfoparser.has_solution)
            {
                //执行BPA程序，N-1计算
                CallPfnt(out_file);
                pfo_file_path = "./bpa_temp/static_analysis_temp/dat_temp_N-1.pfo";
                pfoparser.pfofile = pfo_file_path;
                pfoparser.N_1PfoParse();
                if (pfoparser.has_solution)
                {
                    Pfo2database(
                        1,
                        pfo_file_path,
                        pfoparser.BaseOverInfo,
                        pfoparser.BrekPro_BusInfo,
                        pfoparser.BreakProInfo,
                        pfoparser.NoneInfo);

                    N_1PfoDataToPre();
                    return true;
                }
                else
                {
                    return NO_SOLUTION;
                }
            }
            else
            {
                return NO_SOLUTION;
            }
        }

        void N_KAnalysis::N_1PfoDataToPre()
        {
            try
            {
                SqliteHelperDataBase db;
                db.open(database);

                ostringstream oss;

                db.execDML("begin transaction;");

                // 负载率用百分数
                db.execDML("UPDATE ssa_baseover SET load_pu = load_pu / 100 WHERE load_pu > 50;");
                db.execDML("UPDATE ssa_out_over SET load_pu = load_pu / 100 WHERE load_pu > 50;");

                oss.str("");
                oss << "INSERT INTO ssa_out_over("
                    << "caseid, n_k_flag, out_string, over_string, load_pu, over_type) "
                    << "SELECT caseid, n_k_flag, out_string, over_string, load_pu, over_type "
                    << "FROM ssa_line_overload;";
                db.execDML(oss.str().c_str());

                oss.str("");
                oss << "INSERT INTO ssa_out_over("
                    << "caseid, n_k_flag, out_string, over_string, load_pu, over_type) "
                    << "SELECT caseid, n_k_flag, out_string, over_string, voltage_pu, over_type "
                    << "FROM ssa_bus_overvoltage;";
                db.execDML(oss.str().c_str());

                // 删除初始潮流过负荷情况
                //db.execDML("DELETE FROM ssa_out_over WHERE BreakVol1=0;");

                // outset_overset
                oss.str("");
                oss << "SELECT DISTINCT out_string FROM ssa_out_over as A "
                    << "WHERE (SELECT count(*) FROM ssa_out_over WHERE over_string = A.over_string) > 1;";
                // db.execDML(oss.str().c_str());
                SqliteHelperTable for_outset_overset = db.getTable(oss.str().c_str());
                int out_num = for_outset_overset.numRows();
                for (int i = 0; i < out_num; i++)
                {
                    for_outset_overset.setRow(i);
                    string out_string = for_outset_overset.getStringField(0);
                    for (int j = i + 1; j < out_num; j++)
                    {
                        for_outset_overset.setRow(j);
                        string out_string_repeat = for_outset_overset.getStringField(0);
                        oss.str("");
                        oss << "INSERT INTO ssa_outset_overset SELECT * FROM "
                            << "(SELECT * FROM ssa_out_over as A WHERE "
                            << "(SELECT count(*) FROM ssa_out_over WHERE over_string = A.over_string) > 1) "
                            << "WHERE (over_string in("
                            << "SELECT over_string FROM "
                            << "(SELECT * FROM ssa_out_over as A WHERE "
                            << "(SELECT count(*) FROM ssa_out_over WHERE over_string = A.over_string) > 1) "
                            << "WHERE (out_string = '" << out_string.c_str() << "'))) "
                            << "and (over_string in (SELECT over_string FROM "
                            << "(SELECT * FROM ssa_out_over as A  WHERE "
                            << "(SELECT count(*) FROM ssa_out_over WHERE over_string = A.over_string) > 1) "
                            << "WHERE (out_string = '" << out_string_repeat.c_str() << "'))) and ("
                            << "((out_string = '" << out_string.c_str() << "') or (out_string = '"
                            << out_string_repeat.c_str() << "')));";
                        db.execDML(oss.str().c_str());
                    }
                }

                // overset_outset
                oss.str("");
                oss << "SELECT DISTINCT out_string FROM ssa_out_over as A "
                    << "WHERE (SELECT count(*) FROM ssa_out_over WHERE out_string = A.out_string) > 1;";
                // db.execDML(oss.str().c_str());
                SqliteHelperTable for_overset_outset = db.getTable(oss.str().c_str());
                int over_num = for_overset_outset.numRows();
                for (int i = 0; i < over_num; i++)
                {
                    for_overset_outset.setRow(i);
                    string over_string = for_overset_outset.getStringField(0);
                    for (int j = i + 1; j < over_num; j++)
                    {
                        for_overset_outset.setRow(j);
                        string over_string_repeat = for_overset_outset.getStringField(0);
                        oss.str("");
                        oss << "INSERT INTO ssa_overset_outset SELECT * FROM "
                            << "(SELECT * FROM ssa_out_over as A WHERE "
                            << "(SELECT count(*) FROM ssa_out_over WHERE out_string = A.out_string) > 1) "
                            << "WHERE (out_string in("
                            << "SELECT out_string FROM "
                            << "(SELECT * FROM ssa_out_over as A WHERE "
                            << "(SELECT count(*) FROM ssa_out_over WHERE out_string = A.out_string) > 1) "
                            << "WHERE (over_string = '" << over_string.c_str() << "'))) "
                            << "and (out_string in (SELECT out_string FROM "
                            << "(SELECT * FROM ssa_out_over as A WHERE "
                            << "(SELECT count(*) FROM ssa_out_over WHERE out_string = A.out_string) > 1) "
                            << "WHERE (over_string = '" << over_string_repeat.c_str() << "'))) and ("
                            << "((over_string = '" << over_string.c_str() << "') or (over_string = '"
                            << over_string_repeat.c_str() << "')));";
                        db.execDML(oss.str().c_str());
                    }
                }

                db.execDML("commit transaction;");

                db.close();
            }
            catch (std::exception&)
            {
                throw JGG::IOException();
            }
        }

        bool N_KAnalysis::GetN_2Dats()
        {
            SqliteHelperDataBase db;
            SqliteHelperBuffer bufSQL;
            db.open(database);

            ostringstream oss("");
            for (int i = 0; i < Zone.size() - 1; i++)
            {
                oss << "select a.[StartNum],a.[EndNum],a.[StartName],"
                    << "a.[StartVol],a.[EndName],a.[EndVol], d.[ShuntFlag] "
                    << "from LineList a,buslist b,Zonelist c, LineNormalList d "
                    << "where (a.[StartNum] = b.[BusID]) and b.[BusZoneID] = c.[ZoneID] "
                    << "and d.[LineID] = a.[LineID] "
                    << "and c.[ZoneName_EN] = '" << Zone[i].c_str() << "' "
                    << "and (b.[BusVol] >=(" << Voltage[0] << ") "
                    << "and b.[BusVol] <=(" << Voltage[1] << ") ) "
                    << "and (a.[caseid] = " << caseid << ") union all ";
            }
            oss << "select a.[StartNum],a.[EndNum],a.[StartName],"
                << "a.[StartVol],a.[EndName],a.[EndVol], d.[ShuntFlag] "
                << "from LineList a,buslist b,Zonelist c, LineNormalList d "
                << "where (a.[StartNum] = b.[BusID]) and b.[BusZoneID] = c.[ZoneID] "
                << "and d.[LineID] = a.[LineID] "
                << "and c.[ZoneName_EN] = '" << Zone[Zone.size() - 1].c_str() << "' "
                << "and (b.[BusVol] >=(" << Voltage[0] << ") "
                << "and b.[BusVol] <=(" << Voltage[1] << ") ) "
                << "and (a.[caseid] = " << caseid << ");";
            bufSQL.format(oss.str().c_str());

            SqliteHelperTable LineTable = db.getTable(bufSQL);
            int numberOfLines = LineTable.numRows();
            db.close();

            //N-2文件批量回写
            //判断是否所有N-2均不收敛
            //bool isAllFileNoSolution = true;
            int n2FileCount = 0;
            for (int n2Line1 = 0; n2Line1 < numberOfLines; n2Line1++)
            {
                Line LinePar;
                LinePar.StartNum = LineTable.getIntField("StartNum");
                LinePar.EndNum = LineTable.getIntField("EndNum");
                LinePar.ShuntFlag = LineTable.getTypeField<std::string>("ShuntFlag");
                std::vector <Line> AnnotateLines;
                AnnotateLines.push_back(LinePar);

                for (int n2Line2 = n2Line1 + 1; n2Line2 < numberOfLines; n2Line2++)
                {
                    n2FileCount += 1;

                    LineTable.setRow(n2Line2);
                    Line LinePar;
                    LinePar.StartNum = LineTable.getIntField("StartNum");
                    LinePar.EndNum = LineTable.getIntField("EndNum");
                    LinePar.ShuntFlag = LineTable.getTypeField<std::string>("ShuntFlag");
                    AnnotateLines.push_back(LinePar);

                    oss.str("");
                    oss << "dat_temp_N-2_" << n2FileCount << ".dat";
                    string OutFile = oss.str();
                    DatWriteBack datWriteBack(database, caseid, OutFile);
                    datWriteBack.GetBaseDatFromDb(AnnotateLines);
                    CallPfnt(oss.str());

                    oss.str("");
                    oss << "dat_temp_N-2_" << n2FileCount << ".pfo";
                    string PfoFilePath = oss.str();
                    BPAFilesIO::PfoParse pfoparser(database, caseid, PfoFilePath);
                    pfoparser.BasePfoParse();
                }
            }

            return true;
        }

        bool N_KAnalysis::N_2Analysis()
        {
            fstream log("LogInfo.txt", ios::app);
            log << "N-2 pfo 文件批量处理！" << endl;

            std::vector <std::string> files =
                JGG::filesystem::CPath::has_extension(".\\bpa_temp\\static_analysis_temp\\", "pfo", false);

            // database
            JGG::SqliteHelperDataBase db;
            JGG::SqliteHelperBuffer bufSQL;
            db.open(database);

            std::ostringstream oss;

            for (int i = 0; i < files.size(); i++)
            {
                // 选出N-2_*.pfo文件
                if (strstr(files[i].c_str(), "dat_temp_N-2_"))
                {
                    string filename = files[i];
                    BPAFilesIO::PfoParse pfoparser(database, caseid, filename);
                    pfoparser.BasePfoParse();
                    Pfo2database(2, files[i], pfoparser.BusResultList, pfoparser.LineResultList);
                }
            }
            return true;
        }

        bool N_KAnalysis::GetN_3Dats()
        {
            SqliteHelperDataBase db;
            SqliteHelperBuffer bufSQL;
            db.open(database);

            ostringstream oss("");
            for (int i = 0; i < Zone.size() - 1; i++)
            {
                oss << "select a.[StartNum],a.[EndNum],a.[StartName],"
                    << "a.[StartVol],a.[EndName],a.[EndVol], d.[ShuntFlag] "
                    << "from LineList a,buslist b,Zonelist c, LineNormalList d "
                    << "where (a.[StartNum] = b.[BusID]) and b.[BusZoneID] = c.[ZoneID] "
                    << "and d.[LineID] = a.[LineID] "
                    << "and c.[ZoneName_EN] = '" << Zone[i].c_str() << "' "
                    << "and (b.[BusVol] >=(" << Voltage[0] << ") "
                    << "and b.[BusVol] <=(" << Voltage[1] << ") ) "
                    << "and (a.[caseid] = " << caseid << ") union all ";
            }
            oss << "select a.[StartNum],a.[EndNum],a.[StartName],"
                << "a.[StartVol],a.[EndName],a.[EndVol], d.[ShuntFlag] "
                << "from LineList a,buslist b,Zonelist c, LineNormalList d "
                << "where (a.[StartNum] = b.[BusID]) and b.[BusZoneID] = c.[ZoneID] "
                << "and d.[LineID] = a.[LineID] "
                << "and c.[ZoneName_EN] = '" << Zone[Zone.size() - 1].c_str() << "' "
                << "and (b.[BusVol] >=(" << Voltage[0] << ") "
                << "and b.[BusVol] <=(" << Voltage[1] << ") ) "
                << "and (a.[caseid] = " << caseid << ");";
            bufSQL.format(oss.str().c_str());
            SqliteHelperTable LineTable = db.getTable(bufSQL);
            int numberOfLines = LineTable.numRows();
            db.close();

            //N-3文件批量回写
            //判断是否所有N-3均不收敛
            bool isAllFileNoSolution = true;
            int n3FileCount = 0;
            for (int n3File1 = 0; n3File1 < numberOfLines; n3File1++)
            {
                LineTable.setRow(n3File1);
                Line LinePar;
                LinePar.StartNum = LineTable.getIntField("StartNum");
                LinePar.EndNum = LineTable.getIntField("EndNum");
                LinePar.ShuntFlag = LineTable.getTypeField<std::string>("ShuntFlag");
                std::vector <Line> AnnotateLines;
                AnnotateLines.push_back(LinePar);
                for (int n3File2 = n3File1 + 1; n3File2 < numberOfLines; n3File2++)
                {
                    LineTable.setRow(n3File2);
                    Line LinePar;
                    LinePar.StartNum = LineTable.getIntField("StartNum");
                    LinePar.EndNum = LineTable.getIntField("EndNum");
                    LinePar.ShuntFlag = LineTable.getTypeField<std::string>("ShuntFlag");
                    std::vector <Line> AnnotateLines;
                    AnnotateLines.push_back(LinePar);

                    for (int n3File3 = n3File2 + 1; n3File3 < numberOfLines; n3File3++)
                    {
                        n3FileCount += 1;

                        LineTable.setRow(n3File3);
                        Line LinePar;
                        LinePar.StartNum = LineTable.getIntField("StartNum");
                        LinePar.EndNum = LineTable.getIntField("EndNum");
                        LinePar.ShuntFlag = LineTable.getTypeField<std::string>("ShuntFlag");
                        std::vector <Line> AnnotateLines;
                        AnnotateLines.push_back(LinePar);

                        oss.str("");
                        oss << "dat_temp_N-3_" << n3FileCount << ".dat";
                        string OutFile = oss.str();
                        DatWriteBack obj(database, caseid, OutFile);
                        obj.GetBaseDatFromDb(AnnotateLines);
                        CallPfnt(oss.str());
                    }
                }
            }
            return true;
        }

        bool N_KAnalysis::N_3Analysis()
        {
            fstream log("LogInfo.txt", ios::app);
            log << "N-3 pfo 文件批量处理！" << endl;

            std::vector <std::string> files =
                JGG::filesystem::CPath::has_extension(".\\bpa_temp\\static_analysis_temp\\", "pfo", false);

            // database
            JGG::SqliteHelperDataBase db;
            JGG::SqliteHelperBuffer bufSQL;
            db.open(database);

            std::ostringstream oss;

            for (int i = 0; i < files.size(); i++)
            {
                // 选出N-3_*.pfo文件
                if (strstr(files[i].c_str(), "dat_temp_N-3_"))
                {
                    string n3PfoFile = files[i];
                    BPAFilesIO::PfoParse pfoParser(database, caseid, n3PfoFile);
                    pfoParser.BasePfoParse();
                    Pfo2database(3, files[i], pfoParser.BusResultList, pfoParser.LineResultList);
                }
            }
            return true;
        }

        bool N_KAnalysis::CallPfnt(string DatFilePath)
        {
            string pfntexe = ".\\bpa_temp\\static_analysis_temp\\pfnt.exe";
            std::string command = pfntexe + " .\\bpa_temp\\static_analysis_temp\\" + DatFilePath;
            Process processpfnt(command);
            int exit_status = processpfnt.get_exit_status();
            cout << exit_status;
            return true;
        }

        std::string N_KAnalysis::CharToChange(std::string str)
        {
            std::string s1 = "'";
            std::string s2 = "’";
            if (strstr(str.c_str(), "'"))
            {
                std::string::size_type pos = str.find(s1);
                str.replace(pos, 1, s2);
                return str;
            }
            else
                return str;
        }

        void N_KAnalysis::Pfo2database(
            int n_k_flag,
            std::string pfo_filename,
            BPAFilesIO::BusResultVector bus_overvoltage_list,
            BPAFilesIO::LineResultVector line_overload_list)
        {
            try
            {
                JGG::SqliteHelperDataBase db;
                db.open(database);

                std::ostringstream oss;

                db.execDML("begin transaction;");

                // get out string
                std::string out_string = getN23OutString();

                // 写入bus_overvoltage
                for (unsigned int i = 0; i < bus_overvoltage_list.size(); i++)
                {
                    std::string strtemp = CharToChange(bus_overvoltage_list[i].BusName.c_str());
                    oss.str("");
                    oss << "INSERT INTO bus_overvoltage"
                        << "(caseid, n_k_flag, filename, out_string, over_string, voltage_pu)"
                        << "values (" << caseid << "," << n_k_flag << ",'" << pfo_filename << "',"
                        << "'" << out_string << "',"
                        << "'" << strtemp << bus_overvoltage_list[i].BusVol << "',"
                        << bus_overvoltage_list[i].BusVolValue << ");";
                    db.execDML(oss.str().c_str());
                }

                // 写入line_overload
                for (unsigned int i = 0; i < line_overload_list.size(); i++)
                {
                    std::string strtemp1 = CharToChange(line_overload_list[i].StartBusName.c_str());
                    std::string strtemp2 = CharToChange(line_overload_list[i].EndBusName.c_str());
                    oss.str("");
                    oss << "insert into line_overload ("
                        << "caseid, n_k_flag, filename, out_string, over_string, load_pu)"
                        << "values (" << caseid << "," << n_k_flag << ",'" << pfo_filename << "',"
                        << "'" << out_string << "',"
                        << "'" << strtemp1 << " " << line_overload_list[i].StartBusVol << "  "
                        << strtemp2 << " " << line_overload_list[i].EndBusVol << "  "
                        << line_overload_list[i].ShuntFlag << "',"
                        << line_overload_list[i].PercentCurrent << ");";
                    db.execDML(oss.str().c_str());
                }

                db.execDML("commit transaction;");

                db.close();
            }
            catch (std::exception&)
            {
                throw JGG::IOException();
            }
        }

        void N_KAnalysis::Pfo2database(
            int n_k_flag,
            std::string pfo_filename,
            BPAFilesIO::N_1pfo_BaseOverVector baseover_list,
            BPAFilesIO::N_1pfo_BreakPro_BusVector bus_overvoltage_list,
            BPAFilesIO::N_1pfo_BreakProVetor line_overload_list,
            BPAFilesIO::N_1pfo_NoneVector divergence_list)
        {
            JGG::SqliteHelperDataBase db;
            db.open(database);

            std::stringstream oss;

            db.execDML("begin transaction;");

            // base over
            for (unsigned int i = 0; i < baseover_list.size(); i++)
            {
                std::string strtemp1 = CharToChange(baseover_list[i].BusName_1.c_str());
                std::string strtemp2 = CharToChange(baseover_list[i].BusName_2.c_str());
                std::string strtemp3 = "初始潮流越限";
                oss.str("");
                oss << "INSERT INTO ssa_baseover"
                    << "(caseid, n_k_flag, filename, over_string, load_pu, over_type)"
                    << "values (" << caseid << "," << n_k_flag << ",'" << pfo_filename << "',"
                    << "'" << strtemp1.c_str() << baseover_list[i].BaseVol_1
                    << strtemp2.c_str() << baseover_list[i].BaseVol_2 << "',"
                    << baseover_list[i].Loading << ",'" << strtemp3 << "');";
            }

            // bus overvoltage
            for (unsigned int i = 0; i < bus_overvoltage_list.size(); i++)
            {
                std::string strtemp1 = CharToChange(bus_overvoltage_list[i].BrekLine_Bus1.c_str());
                std::string strtemp2 = CharToChange(bus_overvoltage_list[i].BrekLine_Bus2.c_str());
                std::string strtemp3 = CharToChange(bus_overvoltage_list[i].BusPro.c_str());
                std::string strtemp4 = "节点过电压";
                oss.str("");
                oss << "INSERT INTO ssa_bus_overvoltage"
                    << "(caseid, n_k_flag, filename, out_string, over_string, voltage_pu, over_type)"
                    << "values (" << caseid << "," << n_k_flag << ",'" << pfo_filename << "',"
                    << "'" << strtemp1 << bus_overvoltage_list[i].BaseVol_1 << "  "
                    << strtemp2 << bus_overvoltage_list[i].BaseVol_2 << "',"
                    << "'" << strtemp3 << bus_overvoltage_list[i].BaseVol << "',"
                    << bus_overvoltage_list[i].Volpu << ",'" << strtemp4 << "');";
                db.execDML(oss.str().c_str());
            }

            // line overload
            for (unsigned int i = 0; i < line_overload_list.size(); i++)
            {
                std::string strtemp1 = CharToChange(line_overload_list[i].BrekLine_Bus1.c_str());
                std::string strtemp2 = CharToChange(line_overload_list[i].BrekLine_Bus2.c_str());
                std::string strtemp3 = CharToChange(line_overload_list[i].ProLine_Bus1.c_str());
                std::string strtemp4 = CharToChange(line_overload_list[i].ProLine_Bus2.c_str());
                std::string strtemp5 = "线路过负荷";
                oss.str("");
                oss << "insert into ssa_line_overload ("
                    << "caseid, n_k_flag, filename, out_string, over_string, load_pu)"
                    << "values (" << caseid << "," << n_k_flag << ",'" << pfo_filename << "',"
                    << "'" << strtemp1 << line_overload_list[i].BrekLine_BaseVol_1 << "  "
                    << strtemp2 << line_overload_list[i].BrekLine_BaseVol_2 << "',"
                    << "'" << strtemp3 << line_overload_list[i].ProLine_BaseVol_1
                    << strtemp4 << line_overload_list[i].ProLine_BaseVol_2 << "',"
                    << line_overload_list[i].LoadRate << ",'" << strtemp5 << "');";
                db.execDML(oss.str().c_str());
            }

            // divergence
            for (unsigned int i = 0; i < divergence_list.size(); i++)
            {
                std::string strtemp1 = CharToChange(divergence_list[i].BrekLine_Bus1.c_str());
                std::string strtemp2 = CharToChange(divergence_list[i].BrekLine_Bus2.c_str());
                oss.str("");
                oss << "INSERT INTO ssa_divergence ("
                    << "caseid, n_k_flag, filename, out_string, problem)"
                    << "values (" << caseid << "," << n_k_flag << ",'" << pfo_filename << "',"
                    << "'" << strtemp1 << divergence_list[i].BaseVol_1 << "  "
                    << strtemp2 << divergence_list[i].BaseVol_2 << "',"
                    << "'" << divergence_list[i].Problem << "');";
            }

            db.execDML("commit transaction;");

            db.close();
        }

        std::string N_KAnalysis::getN23OutString()
        {
            std::string OutString;

            SqliteHelperDataBase db;
            SqliteHelperBuffer bufSQL;
            db.open(database);

            bufSQL.format(" select * from BusList where  caseid = (%d);", caseid);			//筛出该母线公共信息
            SqliteHelperTable Table_BusList = db.getTable(bufSQL);
            bufSQL.format(" select * from LineList where  caseid = (%d);", caseid);			//筛出该线路公共信息
            SqliteHelperTable Table_LineList = db.getTable(bufSQL);

            stringstream oss;
            oss.str("");
            oss << "select * from LineNormalList a,lineList b where a.[LineID] = b.[LineID] "
                << "and a.[caseid] = b.[caseid] and a.[caseid] = " << caseid << " group by a.[LineID];";
            //筛出该普通线路信息
            SqliteHelperTable Table_LineNormalList = db.getTable(oss.str().c_str());
            int LineNormalNum = Table_LineNormalList.numRows();

            for (int i = 0; i < AnnotateLines.size(); i++)
            {
                for (int j = 0; j < LineNormalNum; j++)
                {
                    if (Table_LineNormalList.getIntField(25) == AnnotateLines[i].StartNum
                        && Table_LineNormalList.getIntField(26) == AnnotateLines[i].EndNum
                        && Table_LineNormalList.getStringField(15) == AnnotateLines[i].ShuntFlag)
                    {
                        Table_LineList.setRow(Table_LineNormalList.getIntField(1) - 1);//查询基础信息
                        Table_BusList.setRow(Table_LineList.getIntField(3) - 1);		//定位到始端母线

                        OutString = Table_BusList.getStringField("BusName");
                        oss.str("");
                        oss << Table_BusList.getFloatField("BusVol");
                        OutString = OutString + "  " + oss.str() + "    ";
                    }
                }
            }

            return OutString;
        }

    }
}

